<template>
  <view class="map-wrapper">
		<!-- #ifdef APP-PLUS || H5 -->
     <div id="center-marker">+</div>
    <view id="map" class="map-box"
    :hk1980="markerHk1980"  :change:hk1980="mapRender.hk1980LandingPoint"
    :clearm="clearMarker"  :change:clearm="mapRender.resetMap"
    :markers="markersList"  :change:markers="mapRender.searchForLandingPoint"
    :center="mapTocenter"  :change:center="mapRender.flyTocenterRjs"
    :geodetic="geodeticPoint"  :change:geodetic="mapRender.geodeticLandingPoint"
    :polygon="polygonLotgla"  :change:polygon="mapRender.lotglaLandingPoint"

    :enterprise="enterprisePoints"  :change:enterprise="mapRender.fetchEnterprisePointsInView"
    :dynamic="dynamicIcons"  :change:dynamic="mapRender.loadDynamicIconsCategory"
    :lotglaState="lotglaLayerState"  :change:lotglaState="mapRender.layerStateManagementLotglaRjs"
    :geodeticState="geodeticLayerState"  :change:geodeticState="mapRender.layerStateManagementGeodeticRjs"
    :position="currentPosition"  :change:position="mapRender.getCurrentPosition"
    ></view>
		<!-- #endif -->
		<!-- #ifndef APP-PLUS || H5 -->
		<view>环境不支持!!!</view>
		<!-- #endif -->
  </view>
</template>

<script lang="ts">
import {AllGEODETIC,HKMAPgetCategory } from '@/api/system/map'
import { useUserStore } from '@/stores';
import config from '@/config'
import { mapStore } from '@/stores';
import { ref } from 'vue'

const locationTimer = ref<null | number>(null);

// 声明mapRender类型
declare module '@vue/runtime-core' {
  interface ComponentCustomProperties {
    mapRender: any;
  }
}

export default {
  data() {
    return {
      dynamics: false,
      isUpdating: false,
      markersList: {} as { name: string, params?: any },
      clearMarker: false,
      mapTocenter:  {} as { center: any[], params?: any ,isLotgla?:boolean, isGeodetic?:boolean},
      markerHk1980: {},
      markerLotgla: {},
      animateData: {},
      clearPoint: false,
      polygonLotgla:[] as any[],
      enterprisePoints:[] as any[],
      dynamicIcons: {},
      geodeticPoint:[] as any[],
      currentCallback: (data:any,mode:any) => { },
      memberId: useUserStore().user_id,
      lotglaLayerState: "",
      geodeticLayerState: "",
      currentPosition: {} as any,
      // 新增：位置获取控制参数
      locationConfig: {
        // 根据平台设置不同的更新间隔
        updateInterval: 0, // 将在mounted中设置
        lastUpdateTime: 0,
        minInterval: 5000, // 最小间隔时间
        goodAccuracy: 10, // 认为精度较好的阈值（米）
        consecutiveGoodCount: 0, // 连续好精度的次数
        maxGoodCount: 3 // 达到这个次数后降低频率
      }
    }

  },
  emits: ['click', 'mclick','tclick', 'locationDetails'],
  mounted() {
    // 根据平台设置不同的位置更新间隔
    // #ifdef APP-PLUS
    // 安卓设备使用更长的间隔时间
    this.locationConfig.updateInterval = 5000; // 30秒
    this.locationConfig.minInterval = 5000; // 最小10秒
    // #endif

    // #ifdef H5
    // 浏览器环境使用相对较短的间隔
    this.locationConfig.updateInterval = 15000; // 15秒
    this.locationConfig.minInterval = 5000; // 最小5秒
    // #endif
  },
  computed: {
      mapStore() {
          return mapStore()
      },
      lotgla() {
          return this.mapStore.lotgla
      },
      geodetic() {
          return this.mapStore.geodetic
      },
      position() {
          return this.mapStore.position
      }
  },
  watch: {
    lotgla(val:any) {
      this.lotglaLayerState = val
    },
    geodetic(val:any) {
      this.geodeticLayerState = val
    },
    position(val:any) {
      if(val){
        this.startLocationUpdate()
      }else{
        this.currentPosition = {isOpen:false}
        this.stopLocationUpdate()
      }
    }
  },
  methods: {
    startLocationUpdate() {
      if (this.isUpdating) return;
      this.isUpdating = true;


      // 立即获取一次位置
      this.getLocationWithThrottle(true);

      // 设置定时更新
      locationTimer.value = setInterval(() => {
        this.getLocationWithThrottle();
      }, this.locationConfig.updateInterval);
    },
    // 停止定位
    stopLocationUpdate() {

      if (locationTimer.value) {
        clearInterval(locationTimer.value);
        locationTimer.value = null;
      }

      this.isUpdating = false;

      // 重置位置配置
      this.locationConfig.consecutiveGoodCount = 0;
      this.locationConfig.lastUpdateTime = 0;

      // 同时停止指南针监听以节省电池
      this.stopCompass();

      // 触发位置详情关闭事件
      this.$emit('locationDetails', false);
    },
    offscaleLocation(){
      this.mapStore.SET_POSITION(false)
      this.stopLocationUpdate()
      uni.showToast({
        title: '您當前位置不在香港範圍內',
        icon: 'none'
      })
    },
    successLocation(){
      uni.showToast({
        title: '開啟定位成功',
        icon: 'none'
      })
    },
    // 智能节流的位置获取方法
    getLocationWithThrottle(isMove?: boolean) {
      const now = Date.now();

      // 检查是否达到最小间隔时间
      if (now - this.locationConfig.lastUpdateTime < this.locationConfig.minInterval) {
        return;
      }

      this.locationConfig.lastUpdateTime = now;
      this.getLocation(isMove);
    },
    getLocation(isMove?:boolean) {
      // 根据平台调整定位参数
      let locationOptions: any = {
        type: 'wgs84',
        altitude: true, // 安卓设备需要明确请求高度数据
      };

      // #ifdef APP-PLUS
      // 安卓设备使用相对保守的设置
      locationOptions.isHighAccuracy = this.locationConfig.consecutiveGoodCount < 2; // 初期使用高精度
      locationOptions.highAccuracyExpireTime = 8000; // 缩短超时时间
      // #endif

      // #ifdef H5
      // 浏览器环境使用标准设置
      locationOptions.isHighAccuracy = true;
      locationOptions.highAccuracyExpireTime = 10000;
      // #endif

      uni.getLocation({
        ...locationOptions,
        success: (res: any) => {
          if(res.errMsg=="getLocation:ok"){
          // ========== 测试模式：随机香港位置 ==========
          // const hongKongLocations = [
          //   { lng: 114.17218, lat: 22.29770, name: '中环' },
          //   { lng: 114.19469, lat: 22.30256, name: '铜锣湾' },
          //   { lng: 114.20861, lat: 22.28333, name: '太古' },
          //   { lng: 114.16472, lat: 22.31917, name: '旺角' },
          //   { lng: 114.18111, lat: 22.27833, name: '香港仔' },
          // ];

          // // 随机选择一个位置，或者按顺序选择
          // const testLocation = hongKongLocations[Math.floor(Math.random() * hongKongLocations.length)]; // 或使用 Math.floor(Math.random() * hongKongLocations.length)
          // res.longitude = testLocation.lng;
          // res.latitude = testLocation.lat;
          // res.accuracy = 5;
          // console.log('🧪 测试位置:', testLocation.name);
          // ============================================
            // 增强位置信息，包含所有可用数据
            const resAny = res as any; // 使用类型断言处理uni-app类型限制

            // 检查GPS高度数据可用性
            let altitude = res.altitude || resAny.altitude || 0;
            if (altitude === null || altitude === undefined) {
              console.warn('GPS高度数据不可用，可能的原因：设备不支持或GPS信号弱');
              altitude = 0;
            }

            // 检查方向数据可用性
            let direction = resAny.direction || resAny.heading || 0;

            const enhancedPosition = {
              ...res,
              isMove,
              isOpen: true,
              // 传递配置状态到 renderjs
              isGeodetic: this.geodetic,
              isLotgla: this.lotgla,
              // 确保包含所有位置相关信息
              longitude: res.longitude || 0,
              latitude: res.latitude || 0,
              accuracy: res.accuracy || 0, // 精度误差(米)
              altitude: altitude, // GPS高度(米)
              speed: resAny.speed || 0, // 速度(m/s)
              direction: direction, // 方向角(度)
              timestamp: new Date().getTime(), // 添加时间戳
              // 坐标系信息
              coordinateSystem: 'WGS84',
              // 数据质量标记
              hasValidAltitude: altitude !== 0,
              hasValidDirection: direction !== 0
            };
            this.currentPosition = enhancedPosition;

            // 智能频率调节逻辑
            this.adjustUpdateFrequency(enhancedPosition.accuracy);

            // 触发位置详情显示事件
            this.$emit('locationDetails', enhancedPosition);
          }else{
            this.mapStore.SET_POSITION(false)
            this.stopLocationUpdate()
            uni.showToast({
              title: '开启定位失败',
              icon: 'none'
            })
          }
        },
        fail: (err: any) => {
          console.error('定位失败:', err);
          this.mapStore.SET_POSITION(false)
          this.stopLocationUpdate()
          uni.showToast({
            title: '开启定位失败',
            icon: 'none'
          })
        }
      });
    },

    // 停止指南针监听
    stopCompass() {
      // #ifdef APP-PLUS
      uni.stopCompass();
      // 移除所有指南针事件监听器
      uni.offCompassChange(() => {});
      // #endif
    },
    updateHk198(data: any) {
      if(data?.callback){
        this.currentCallback = data.callback
      }
      data.isLotgla = this.lotgla;
      data.isGeodetic = this.geodetic;

      const rand = Math.random();
      this.markerHk1980 = {...data,rand}
    },
    clearAllMarkers() {
      this.clearMarker = !this.clearMarker
    },
    // 设置回调函数（用于定位模式等场景）
    setCallback(callback: any) {
      if(callback && typeof callback === 'function') {
        this.currentCallback = callback
      }
    },
    updateMarkers(points: string, params?: any, callback?: any) {
      if (!points || points.length === 0) return
      if(callback){
        this.currentCallback = callback
      }
      const rand = Math.random();
      this.markersList = { ...{ name: points , params,rand}}
    },

    flyTocenter(center: any[],params?: any) {
      const rand = Math.random();
      this.mapTocenter = {...{center,params,isLotgla:this.lotgla, isGeodetic:this.geodetic,rand}}
    },
    geodeticLanding(data: any) {
      if(data?.callback){
        this.currentCallback = data.callback
      }
      const rand = Math.random();
      data.isLotgla = this.lotgla;
      data.isGeodetic = this.geodetic;
      this.geodeticPoint = {...data,rand}
    },
    updatePolygonLotgla(data: any) {
      if(data?.callback){
        this.currentCallback = data.callback
      }
      const rand = Math.random();
      data.isLotgla = this.lotgla;
      data.isGeodetic = this.geodetic;
      this.polygonLotgla = { ...data ,rand}
    },
    callCurrentCallback(parameter:any){
      this.currentCallback(parameter.data, parameter.mode)
    },
    udpAnimate(animate: any) {
      this.animateData = animate
    },
    clearPoints() {
      this.clearPoint = !this.clearPoint
    },
    async getAllGeodetic(){
      let rows = [];
        const params = {
          pageSize: 6000,
          pageNum: 1,
          status: '1',
          memberId: this.memberId
      };

      while (true) {
          const result:any = await AllGEODETIC(params);
          rows.push(...result.rows);
          if (result.rows.length < params.pageSize) break;
          params.pageNum++;
      }

      this.enterprisePoints = rows;
    },
    loadDynamicIcons() {
      //加载产品图标
      HKMAPgetCategory().then(async (data:any) => {
          const domainName = config.baseUrl;
          if (data?.rows.length > 0) {
            let icoRow:any = {}
            const keyFor = (cid: string | number, i: number) => i === 2 ? `product-${cid}-1-0` : `product-${cid}-0-${i}`;
            for (let row of data?.rows) {
                const cid = row.id;
                if(!row?.pic || !row.pic){
                  continue;
                }
                let pic = row.pic.split(',');
                if (pic.length > 0) {
                    while (pic.length < 3) pic.push(pic[0]);
                    for (let i = 0; i < pic.length; i++) {
                      const mapKey = keyFor(cid, i);
                      icoRow[mapKey] = domainName + pic[i];
                    }
                }
            }
            this.dynamicIcons = icoRow
          }
      })
    },
    async imageUrlToBase64(url: string): Promise<string> {
      const response = await fetch(url);
      const blob = await response.blob();

      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onloadend = () => {
          if (typeof reader.result === 'string') {
            resolve(reader.result);
          } else {
            reject('转换失败');
          }
        };
        reader.onerror = reject;
        reader.readAsDataURL(blob);
      });
    },
    onMclick() {
      this.$emit('mclick')
    },
    onClick(data: any) {
      this.$emit('click', data);
    },
    onTClick(data: any) {
      this.$emit('tclick', data);
    },
    // 智能频率调节方法
    adjustUpdateFrequency(accuracy: number) {
      // 如果精度较好，增加连续好精度计数
      if (accuracy <= this.locationConfig.goodAccuracy) {
        this.locationConfig.consecutiveGoodCount++;

        // 达到连续好精度次数后，降低更新频率
        if (this.locationConfig.consecutiveGoodCount >= this.locationConfig.maxGoodCount) {
          this.reduceUpdateFrequency();
        }
      } else {
        // 精度不好，重置计数器并恢复正常频率
        if (this.locationConfig.consecutiveGoodCount > 0) {
          this.locationConfig.consecutiveGoodCount = 0;
          this.restoreUpdateFrequency();
        }
      }
    },

    // 降低更新频率
    reduceUpdateFrequency() {
      const currentInterval = this.locationConfig.updateInterval;
      const newInterval = Math.min(currentInterval * 2, 60000); // 最多60秒

      if (newInterval !== currentInterval) {
        this.locationConfig.updateInterval = newInterval;
        this.restartLocationTimer();
      }
    },

    // 恢复更新频率
    restoreUpdateFrequency() {
      let normalInterval;
      // #ifdef APP-PLUS
      normalInterval = 5000; // 安卓正常频率
      // #endif
      // #ifdef H5
      normalInterval = 15000; // 浏览器正常频率
      // #endif

      if (this.locationConfig.updateInterval !== normalInterval) {
        this.locationConfig.updateInterval = normalInterval;
        this.restartLocationTimer();
      }
    },

    // 重新启动位置定时器
    restartLocationTimer() {
      if (locationTimer.value && this.isUpdating) {
        clearInterval(locationTimer.value);
        locationTimer.value = setInterval(() => {
          this.getLocationWithThrottle();
        }, this.locationConfig.updateInterval);
      }
    },
  }
}

</script>

<script module="mapRender" src="./map-render.js" lang="renderjs"></script>

<style lang="scss" scoped>
.map-wrapper,
.map-box {
  touch-action: none; /* 禁用默认浏览器手势 */
  -ms-touch-action: none;
  -webkit-user-select: none;
  width: 100vw;
  height: 100vh;
}
.map-wrapper #center-marker {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 28px;
  color: red;
  z-index: 9999;
  font-weight: 300;
  pointer-events: none; /* ✅ 不影响鼠标点击、拖动等事件 */
}
#map{
  ::v-deep(.maplibregl-control-container) {
    .maplibregl-ctrl-bottom-right{
      .maplibregl-ctrl-scale{
        margin-bottom: 6vh;
        width: 50px !important;
      }
      .maplibregl-ctrl-attrib{
        display: none;
      }
    }
  }
}
</style>
